package com.gitee.huanminabc.jlambda_sql.segments;



import com.gitee.huanminabc.jlambda_sql.SQL;
import com.gitee.huanminabc.jlambda_sql.SqlKeyword;
import com.gitee.huanminabc.jlambda_sql.base.SqlFun;
import com.gitee.huanminabc.jlambda_sql.base.SqlPick;

import java.util.List;

/**
 * 结构实现类
 * @param <T>
 * @param <Children>
 */
public abstract class SqlStructureImplSegments<T, Children extends  SqlCombineImplSegments<T, Children>>    extends SqlCombineImplSegments<T, Children> implements SqlStructureSegments<Children> {

    public SqlStructureImplSegments() {
    }

    public SqlStructureImplSegments(Class<T> entityClass, SQL sql) {
        super(entityClass, sql);
    }



    @Override
    public Children SELECT() {
        SQL().setCurrentKeyword(SqlKeyword.SELECT);
        SQL().setSelect(true);
        SQL().append("SELECT \n").append(SQL.SELECT_PLACEHOLDER);
        return typedThis;
    }

    @Override
    public Children FROM() {
        SQL().setCurrentKeyword(SqlKeyword.FROM);
        SQL().append("FROM ");
        return typedThis;
    }


    @Override
    public Children WHERE() {
        //去掉最后一个逗号, 因为在where前面有可能是多表,分割 或者set 多个字段最后也会有逗号
        String sql = SQL().getSql().trim();
        if (sql.endsWith(",")) {
            sql = sql.substring(0, sql.length() - 1);
        }
        SQL().setSql(sql);
        SQL().setCurrentKeyword(SqlKeyword.WHERE);
        SQL().append("\nWHERE ");
        return typedThis;
    }




    @Override
    public Children INSERT_INTO() {
        SQL().setCurrentKeyword(SqlKeyword.INSERT);
        SQL().setInsert(true);
        SQL().append("INSERT INTO ");
        //表
        SQL().append(getTableInfo().getTableName());
        //字段
        List<String> columnAll = getColumnAll();
        SQL().append("(");
        StringBuilder sb = new StringBuilder();
        for (String column : columnAll) {
            sb.append(column).append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        SQL().append(sb.toString());
        SQL().append(") ").append("\n");
        return typedThis;
    }

    @Override
    public <Y> Children INSERT_INTO(SqlFun<Y, ?>... columns) {
        SQL().setCurrentKeyword(SqlKeyword.INSERT);
        SQL().setInsert(true);
        SQL().append("INSERT INTO ");
        //表
        SQL().append(getTableInfo().getTableName());
        //字段
        SQL().append("(");
        StringBuilder sb = new StringBuilder();
        for (SqlFun<Y, ?> column : columns) {
            getFunFieldName(column, sqlColumn -> {
                sb.append(sqlColumn.getColumnName()).append(",");
            });
        }
        sb.deleteCharAt(sb.length() - 1);
        SQL().append(sb.toString());
        SQL().append(") ");
        return typedThis;
    }

    @Override
    public final Children VALUES(Object... values) {
        SQL().setCurrentKeyword(SqlKeyword.VALUES);
        SQL().append("VALUES ");
        SQL().append("(");
        StringBuilder sb = new StringBuilder();
        for (Object value : values) {
            //如果是字符串那么就加上单引号
            if(value instanceof String){
                sb.append("'").append(value).append("'").append(",");
            }else{
                sb.append(value).append(",");
            }
        }
        sb.deleteCharAt(sb.length() - 1);
        SQL().append(sb.toString());
        SQL().append(")").append("\n");
        return typedThis;
    }


    @Override
    public Children DELETE() {
        SQL().setCurrentKeyword(SqlKeyword.DELETE);
        SQL().setDelete(true);
        SQL().append("DELETE ");
        //因为delete 后面需要别名
        SQL().append(getTableInfo().getAlias() +" ");
        return typedThis;
    }

    @Override
    public Children SET() {
        SQL().setCurrentKeyword(SqlKeyword.SET);
        SQL().append("SET \n    ");
        return typedThis;
    }

    @Override
    public Children UPDATE() {
        SQL().setCurrentKeyword(SqlKeyword.UPDATE);
        SQL().setUpdate(true);
        SQL().append("UPDATE ");
        return typedThis;
    }

    @Override
    public Children ORDER_BY() {
        SQL().setCurrentKeyword(SqlKeyword.ORDER_BY);
        SQL().append("\nORDER BY ").append(SQL.ORDER_PLACEHOLDER);
        return typedThis;
    }
    @Override
    public Children O_COLUMN(String sql){
        SQL().addOrderColumn(sql);
        return typedThis;
    }
    @Override
    public <Y> Children O_COLUMN(SqlFun<Y, ?>... columns){
        //不能传空
        if(columns==null||columns.length==0){
            throw new RuntimeException("O_COLUMN方法参数不能为空");
        }
        for (SqlFun<Y, ?> column : columns) {
            getFunFieldName(column, sqlColumn -> {
                SQL().addOrderColumn(sqlColumn.getTableName(),sqlColumn.getColumnName());
            });
        }
        return typedThis;
    }
    @Override
    public  Children O_COLUMN(SqlPick<?, ?>... columns){
        //不能传空
        if(columns==null||columns.length==0){
            throw new RuntimeException("O_COLUMN方法参数不能为空");
        }
        for (SqlPick<?, ?> column : columns) {
            getFunFieldName(column.getFunction(), sqlColumn -> {
                SQL().addOrderColumn(sqlColumn.getTableName(),sqlColumn.getColumnName());
            });
        }
        return typedThis;
    }

    @Override
    public Children HAVING() {
        SQL().setCurrentKeyword(SqlKeyword.HAVING);
        SQL().append("\nHAVING ");
        return typedThis;
    }

    @Override
    public Children GROUP_BY() {
        SQL().setCurrentKeyword(SqlKeyword.GROUP_BY);
        SQL().append("\nGROUP BY ").append(SQL.GROUP_PLACEHOLDER);
        return typedThis;
    }
    @Override
    public Children G_COLUMN(String sql){
        SQL().addGroupColumn(sql);
        return typedThis;
    }

    @Override
    public <Y> Children G_COLUMN(SqlFun<Y, ?>...columns){
        //不能传空
        if(columns==null||columns.length==0){
            throw new RuntimeException("G_COLUMN方法参数不能为空");
        }
        for (SqlFun<Y, ?> column : columns) {
            getFunFieldName(column, sqlColumn -> {
                SQL().addGroupColumn(sqlColumn.getTableName(),sqlColumn.getColumnName());
            });
        }
        return typedThis;
    }

    @Override
    public  Children G_COLUMN(SqlPick<?, ?>...columns){
        //不能传空
        if(columns==null||columns.length==0){
            throw new RuntimeException("G_COLUMN方法参数不能为空");
        }
        for (SqlPick<?, ?> column : columns) {
            getFunFieldName(column.getFunction(), sqlColumn -> {
                SQL().addGroupColumn(sqlColumn.getTableName(),sqlColumn.getColumnName());
            });
        }
        return typedThis;

    }

    @Override
    public Children OFFSET() {
        SQL().append("OFFSET ");
        return typedThis;
    }

    //OFFSET
    public Children OFFSET(Integer param) {
        SQL().append(OFFSET()).append(V(param)).append("\n");
        return typedThis;
    }

    @Override
    public Children LIMIT() {
        SQL().append("\nLIMIT ");
        return typedThis;
    }


    //LIMIT
    public Children LIMIT(Integer param) {
        SQL().append(LIMIT()).append(V(param)).append("\n");
        return typedThis;
    }



    //LIMIT OFFSET
    public Children LIMIT(Integer limit, Integer offset) {
        SQL().append(LIMIT()).append(V(limit)).append(" ").append(OFFSET()).append(V(offset)).append("\n");
        return typedThis;
    }

































}
